/*

* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Smart-Shop开源商城系统/ Java商城-首选电商平台系统 请务必保留此注释头信息
* |     开源地址: https://gitee.com/ningbo-qishan/gruul-mall
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     可正常分享和学习源码,未经授权 不可商用！
* |     商业版中台购买/开源版商业授权 联系技术客服
* |     官网:  https://www.73app.cn/
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Copyright (c) 2016-2999 宁波启山智软科技有限公司
* |     版权所有 ,侵权必究！
* ------------------------------------------------------------------------

*/
package com.medusa.gruul.recycling.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medusa.gruul.common.core.constant.CommonConstants;
import com.medusa.gruul.common.core.constant.enums.CommonEnum;
import com.medusa.gruul.common.core.util.CurUserUtil;
import com.medusa.gruul.common.core.util.ResultPageList;
import com.medusa.gruul.common.data.tenant.ShopContextHolder;
import com.medusa.gruul.common.data.tenant.TenantContextHolder;
import com.medusa.gruul.common.dto.CurMiniUserInfoDto;
import com.medusa.gruul.common.dto.CurUserDto;
import com.medusa.gruul.order.api.enums.OrderStatusEnum;
import com.medusa.gruul.order.api.model.OrderVo;
import com.medusa.gruul.recycling.api.entity.RecyclingAssOrder;
import com.medusa.gruul.recycling.mapper.RecyclingAssOrderMapper;
import com.medusa.gruul.recycling.model.vo.MeRecyclingAssOrderListVo;
import com.medusa.gruul.recycling.model.vo.RecyclingSettingVo;
import com.medusa.gruul.recycling.service.IRecyclingAssOrderAccountService;
import com.medusa.gruul.recycling.service.IRecyclingAssOrderService;
import com.medusa.gruul.recycling.service.IRecyclingSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 基金所得订单关联表 服务实现类
 * </p>
 *
 * @author whh
 * @since 2021-04-28
 */
@Service
@Slf4j
public class RecyclingAssOrderServiceImpl extends ServiceImpl<RecyclingAssOrderMapper, RecyclingAssOrder> implements IRecyclingAssOrderService {

    @Autowired
    private IRecyclingSettingService recyclingSettingService;
    @Autowired
    private IRecyclingAssOrderAccountService recyclingAssOrderAccountService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPayOk(OrderVo orderVo) {
        TenantContextHolder.setTenantId(orderVo.getTenantId());
        ShopContextHolder.setShopId(orderVo.getShopId());

//        CurMiniUserInfoDto accountInfo = CurUserUtil.getMiniReqeustAccountInfo();
//        CurUserDto accountInfo = CurUserUtil.getHttpCurUser();
        RecyclingSettingVo service = recyclingSettingService.getByTenantIdSetting();
        if (service.getGoodsFundState().equals(Boolean.FALSE)) {
            log.info("基金功能关闭");
            return;
        }
        RecyclingAssOrder recyclingAssOrder = this.baseMapper.selectOne(
                new QueryWrapper<RecyclingAssOrder>().eq("order_id", orderVo.getId())
        );
        if (recyclingAssOrder != null) {
            return;
        }
        recyclingAssOrder = new RecyclingAssOrder();
        recyclingAssOrder.setCreateTime(orderVo.getPayTime());
        recyclingAssOrder.setOrderId(orderVo.getId());
        recyclingAssOrder.setPayAmount(orderVo.getPayAmount());
        recyclingAssOrder.setShopUserId(Long.valueOf(orderVo.getUserId()));
        recyclingAssOrder.setFundQuota(service.getFundQuota().multiply(new BigDecimal(orderVo.getProductTotalQuantity())));
        recyclingAssOrder.setStatus(CommonConstants.NUMBER_ONE);
        recyclingAssOrder.setNickName(orderVo.getUserName());
        recyclingAssOrder.setAvatarUrl(orderVo.getUserAvatarUrl());
//        recyclingAssOrder.setNickName(accountInfo.getNikeName());
//        recyclingAssOrder.setAvatarUrl(accountInfo.getAvatarUrl());
        recyclingAssOrder.setAvatarUrl(orderVo.getUserAvatarUrl());
        recyclingAssOrder.setProductTotalQuantity(orderVo.getProductTotalQuantity());
        recyclingAssOrder.insertOrUpdate();
        recyclingAssOrderAccountService.addRecyclingAssOrder(recyclingAssOrder);
    }

    @Override
    public ResultPageList<MeRecyclingAssOrderListVo> recyclingAssOrderAccountList(Integer page, Integer size) {
        Page<RecyclingAssOrder> pageResult = this.baseMapper.selectPage(
                new Page<>(page, size),
                new QueryWrapper<RecyclingAssOrder>()
                        .eq("shop_user_id", CurUserUtil.getMiniReqeustAccountInfo().getShopUserId())
                        .eq("status", CommonConstants.NUMBER_ONE)
                        .orderByDesc("create_time")
        );
        List<RecyclingAssOrder> records = pageResult.getRecords();
        ResultPageList<MeRecyclingAssOrderListVo> resultPageList = new ResultPageList<MeRecyclingAssOrderListVo>(CommonEnum.SUCCESS_RESPONSE, pageResult, records);
        if (CollectionUtil.isNotEmpty(records)) {
            List<MeRecyclingAssOrderListVo> listVos = records.stream().map(obj -> {
                MeRecyclingAssOrderListVo vo = new MeRecyclingAssOrderListVo();
                vo.setOrderId(obj.getOrderId());
                vo.setOrderPayTime(obj.getCreateTime());
                vo.setPayAmount(obj.getPayAmount());
                return vo;
            }).collect(Collectors.toList());
            resultPageList.setData(listVos);
        }
        return resultPageList;
    }

    @Override
    public void refundNotify(OrderVo orderVo) {
        RecyclingAssOrder recyclingAssOrder = this.baseMapper.selectOne(
                new QueryWrapper<RecyclingAssOrder>().eq("order_id", orderVo.getId())
        );
        log.info("RecyclingAssOrder: {}", JSON.toJSONString(recyclingAssOrder));
        if (recyclingAssOrder == null) {
            log.info("不存在有效订单: {}", orderVo.getId());
            return;
        }
        //有效订单才可进行回退
        BigDecimal multiply = new BigDecimal(0);
        BigDecimal refundAmount = new BigDecimal(0);
        if (recyclingAssOrder.getStatus().equals(CommonConstants.NUMBER_ONE)) {
            RecyclingAssOrder recyclingAssOrder1 = new RecyclingAssOrder().setId(recyclingAssOrder.getId());
            if (orderVo.getStatus() == OrderStatusEnum.REFUNDED){
                recyclingAssOrder1.setStatus(CommonConstants.NUMBER_TWO);
                recyclingAssOrder.setStatus(CommonConstants.NUMBER_TWO);
            }else {
                multiply = new BigDecimal(orderVo.getRefundQuantity())
                        .multiply(recyclingAssOrder.getFundQuota()
                                .divide(new BigDecimal(recyclingAssOrder.getProductTotalQuantity())));
                recyclingAssOrder1.setFundQuota(recyclingAssOrder.getFundQuota()
                        .subtract(multiply));
                recyclingAssOrder.setFundQuota(recyclingAssOrder.getFundQuota()
                        .subtract(multiply));
                int num = recyclingAssOrder.getProductTotalQuantity() - orderVo.getRefundQuantity();
                log.info("num is ---: {}",num);
                recyclingAssOrder1.setProductTotalQuantity(num);
                if (num <= 0){
                    recyclingAssOrder1.setStatus(CommonConstants.NUMBER_TWO);
                    recyclingAssOrder.setStatus(CommonConstants.NUMBER_TWO);
                }else {
                    recyclingAssOrder.setFundQuota(recyclingAssOrder.getFundQuota()
                            .subtract(multiply));
                }
                refundAmount = orderVo.getRefundAmount();
            }
            recyclingAssOrder1.updateById();
            recyclingAssOrderAccountService.removeRecyclingAssOrder(recyclingAssOrder,multiply,refundAmount);
        }

    }


}
